package com.fenquen.dfs.router.multicast;


import com.fenquen.dfs.router.config.DFSRouterConfig;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramChannel;
import io.netty.channel.socket.InternetProtocolFamily;
import io.netty.channel.socket.nio.NioDatagramChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.net.*;

@Component
public class MulticastReceiver {
    private static final Logger LOGGER = LoggerFactory.getLogger(MulticastReceiver.class);

    @Autowired
    private DFSRouterConfig dfsRouterConfig;

    @Autowired
    private MulticastServerHandler multicastServerHandler;

    public boolean boot() throws Exception {
        InetSocketAddress multicastAddress = new InetSocketAddress(dfsRouterConfig.multicastHost, dfsRouterConfig.multicastPort);

        EventLoopGroup eventLoopGroup = new NioEventLoopGroup();

        Bootstrap bootstrap = new Bootstrap().group(eventLoopGroup)
                .channelFactory(() -> {
                    NioDatagramChannel nioDatagramChannel = new NioDatagramChannel(InternetProtocolFamily.IPv4);
                    System.out.println(nioDatagramChannel);
                    return nioDatagramChannel;
                })
                .localAddress(dfsRouterConfig.multicastLocalHost, multicastAddress.getPort())
                // .option(ChannelOption.IP_MULTICAST_IF, NetworkInterface.getByInetAddress(InetAddress.getByName("192.168.100.60")))
                .option(ChannelOption.SO_REUSEADDR, true)
                .handler(new ChannelInitializer<NioDatagramChannel>() {
                    @Override
                    public void initChannel(NioDatagramChannel ch) {
                        ch.pipeline().addLast(multicastServerHandler);
                    }
                });

        ChannelFuture channelFuture = bootstrap.bind().sync();

        if (channelFuture.isSuccess()) {
            ((DatagramChannel) channelFuture.channel())
                    .joinGroup(multicastAddress,
                            NetworkInterface.getByInetAddress(InetAddress.getByName(dfsRouterConfig.multicastLocalHost)));
            return true;
        }

        LOGGER.error("", channelFuture.cause());

        eventLoopGroup.shutdownGracefully();

        return false;

    }
}
